package com.mlk.engSystem.service.impl;


import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.common.collect.Maps;
import com.mlk.car.mapper.EngCarMapper;
import com.mlk.constant.EngConstant;
import com.mlk.core.component.page.Page;
import com.mlk.core.component.page.Pager;
import com.mlk.core.constants.Constant;
import com.mlk.core.exception.GlobalException;
import com.mlk.core.exception.ParamException;
import com.mlk.core.util.MD5Utils;
import com.mlk.core.util.ServerResponse;
import com.mlk.core.util.SessionUtils;
import com.mlk.deposit.mapper.EngDepositMapper;
import com.mlk.engSystem.mapper.*;
import com.mlk.engSystem.po.*;
import com.mlk.engSystem.service.EngSysEmpService;
import com.mlk.engSystem.vo.EngSysEmpRemainApplyVO;
import com.mlk.engSystem.vo.EngSysEmpVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class EngSysEmpServiceImpl implements EngSysEmpService {

    @Resource
    private EngSysEmpMapper engSysEmpMapper;

    @Resource
    private EngSysRefUserAreaMapper engSysRefUserAreaMapper;

    @Resource
    private EngUserWasteTypeMapper engUserWasteTypeMapper;

    @Resource
    private EngSysEmpRemainApplyMapper engSysEmpRemainApplyMapper;

    @Resource
    private EngSysEmpRemainLogMapper engSysEmpRemainLogMapper;

    @Resource
    private EngDepositMapper engDepositMapper;

    @Resource
    private EngCarMapper engCarMapper;

    @Override
    public EngSysEmp getEmpByOpenId(String openId) {
        return this.engSysEmpMapper.selectOne(EngSysEmp.builder().openId(openId).build());
    }

    @Override
    public Pager listPage() {
        return Pager.adapt(this.engSysEmpMapper.selectAll());
    }

    @Override
    public ServerResponse add(EngSysEmp emp) {
        emp.setPassword(MD5Utils.encode(emp.getPassword()));
        emp.setCreateTime(new Date());
        emp.setCreateName(SessionUtils.getUser().getSysUser().getName());
        return this.engSysEmpMapper.insert(emp) == 0 ?
                ServerResponse.fail("添加失败") : ServerResponse.ok("添加成功");
    }

    @Override
    public ServerResponse modify(EngSysEmp emp) {
        return this.engSysEmpMapper.updateById(emp) == 0 ?
                ServerResponse.fail("修改失败") : ServerResponse.ok("修改成功");
    }

    @Override
    @Transactional
    public ServerResponse allocateArea(List<EngSysRefUserArea> lists, Integer id) {

        // 先删除
        this.engSysRefUserAreaMapper.delete(new EntityWrapper<>(EngSysRefUserArea.builder().userId(id).build()));
        // 批量新增

        if (CollectionUtils.isEmpty(lists)) {
            return ServerResponse.ok("分配成功");
        }
        return this.engSysRefUserAreaMapper.insertBatch(lists) == lists.size() ?
                ServerResponse.ok("操作成功") : ServerResponse.fail("操作失败");
    }

    @Transactional
    @Override
    public ServerResponse allocateWasteType(List<EngUserWasteType> lists, Integer id) {

        this.engUserWasteTypeMapper.delete(new EntityWrapper<>(EngUserWasteType.builder().userId(id).build()));

        if (CollectionUtils.isEmpty(lists)) {
            return ServerResponse.ok("分配成功");
        }

        return this.engUserWasteTypeMapper.insertBatch(lists) == lists.size() ?
                ServerResponse.ok("操作成功") : ServerResponse.fail("操作失败");
    }

    @Override
    @Transactional
    public ServerResponse allocateDeposit(Integer depositId, Integer id) {
        // 实际上就是update 一个数据而已
        return this.engSysEmpMapper.allocateDeposit(depositId, id) == 0 ?
                ServerResponse.fail("分配失败") : ServerResponse.ok("分配成功");
    }

    @Override
    public ServerResponse selectEmpAllCheckedWasteType(Integer id) {
        return ServerResponse.ok(this.engUserWasteTypeMapper.selectList(new EntityWrapper<>(EngUserWasteType.builder().userId(id).build())));
    }

    @Override
    public ServerResponse selectEmpAllArea(Integer id) {
        return ServerResponse.ok(this.engSysRefUserAreaMapper.selectList(new EntityWrapper<>(EngSysRefUserArea.builder().userId(id).build())));
    }

    @Override
    public ServerResponse checkedIsRegistered(String openId) {
        //
        EngSysEmp emp = this.engSysEmpMapper.selectOne(EngSysEmp.builder().openId(openId).build());
        if(emp == null ){
            ServerResponse.fail("该用户没有认证");
        }

        if(emp.getStatus().equals(Constant.status_fail)){
            ServerResponse.fail("该用户被冻结");
        }
        return ServerResponse.ok("该用户已经认证");
    }

    @Override
    @Transactional
    public ServerResponse empVerify(EngSysEmp emp) {
        // 通过账号和密码查询用户是否存在
        List<EngSysEmp> emps = this.engSysEmpMapper.selectList(new EntityWrapper<>(EngSysEmp.builder().empCode(emp.getEmpCode()).build()));

        if (CollectionUtils.isEmpty(emps)) {
            return ServerResponse.fail("账号不存在");
        }
        if (emps.size() > 1) {
            return ServerResponse.fail("管理员分配了两个相同的账号,请联系管理员处理");
        }
        EngSysEmp selectedEmp = emps.get(0);
        if (!StringUtils.equals(MD5Utils.encode(emp.getPassword()), selectedEmp.getPassword())) {
            return ServerResponse.fail("用户的密码错误");
        }

        // 更新一个openID的值
        EngSysEmp updateEmp = EngSysEmp.builder().id(selectedEmp.getId()).openId(emp.getOpenId()).build();
        int count = this.engSysEmpMapper.updateById(updateEmp);
        if (count == 0) {
            return ServerResponse.fail("认证失败");
        }
        return ServerResponse.ok("认证成功");
    }

    /**
     * 业务原申请额度
     *
     * @param apply
     * @return
     */
    @Override
    public ServerResponse applyRemain(EngSysEmpRemainApply apply) {
        EngSysEmp emp = this.engSysEmpMapper.selectOne(EngSysEmp.builder().openId(apply.getOpenId()).build());
        apply.setCreateName(emp.getName());
        apply.setCreateTime(new Date());
        int count = this.engSysEmpRemainApplyMapper.insert(apply);
        if (count == 0) {
            return ServerResponse.fail("申请失败");
        }

        return ServerResponse.ok("申请成功");
    }

    @Override
    @Page
    public Pager applyRemainList(String openId) {
        EngSysEmpRemainApplyVO apply = new EngSysEmpRemainApplyVO();
        apply.setOpenId(openId);
        return Pager.adapt(this.engSysEmpRemainApplyMapper.selectForPage(apply));
    }


    @Override
    @Transactional
    public ServerResponse allocateRemain(EngSysEmpRemainLog log) {
        if(StringUtils.isBlank(log.getOpenId())){
            throw new ParamException("请等待业务员完成小程序认证之后再分配权限额度！");
        }
        log.setCreateName(SessionUtils.getUser().getSysUser().getName());
        log.setCreateTime(new Date());
        log.setType(EngConstant.EMP_REMAIN_LOG_TYPE.ADMIN_ALLOCATE_LOG);
        int count = this.engSysEmpRemainLogMapper.insert(log);
        if (count == 0) {
            return ServerResponse.fail("分配失败");
        }
        // 给员工加上额度
        count = this.engSysEmpMapper.updateRemain(log.getOpenId(), log.getAmount());

        if (count == 0) {
            return ServerResponse.fail("操作失败");
        }
        return ServerResponse.ok("分配成功");
    }

    /**
     * 查询权限余额
     *
     * @param openId
     * @return
     */
    @Override
    public ServerResponse queryMyRemain(String openId) {
        EngSysEmp emp = this.engSysEmpMapper.selectOne(EngSysEmp.builder().openId(openId).build());
        Map<String, Object> result = Maps.newHashMap();
        result.put("remain", emp.getRemain());
        return ServerResponse.ok(result);
    }

    @Override
    public Pager listReportPage(EngSysEmpVO engSysEmpVO) {
        return Pager.adapt(this.engSysEmpMapper.listReportPage(engSysEmpVO));
    }

    @Override
    public ServerResponse isAllocateCar(Integer id) {
        EngSysEmp emp = this.engSysEmpMapper.selectById(id);
        if(emp.getDepositId() == null){
            return ServerResponse.fail("该用户没有分配暂存区");
        }

        return ServerResponse.ok("该用户已经分配暂存区");
    }

    /**
     * 获取员工可以使用的车辆的信息
     * @param id
     * @return
     */
    @Page
    @Override
    public Pager getAllCanUseCar(Integer id) {
        // 实际就是员工所在暂存区内管辖的车辆
        return Pager.adapt(this.engSysEmpMapper.getAllCanUseCar(id));
    }


    /**
     * 分配车辆
     * @param emp
     * @return
     */
    @Override
    public ServerResponse allocateCar(EngSysEmp emp) {
        if(emp.getId() == null){
            emp.setId(this.engSysEmpMapper.selectOne(EngSysEmp.builder().openId(emp.getOpenId()).build()).getId());
            // 放置被覆盖掉
            emp.setOpenId(null);
        }

        int count = 0;
        if(emp.getCarId() == null){
            // 表示解绑车辆信息
            count = this.engSysEmpMapper.unbindCar(emp.getId());
            if(count == 0){
                throw new GlobalException("车辆解绑失败");
            }
            return ServerResponse.ok("车辆解绑成功");
        }

        // 带有车辆的car_id 表示分配车辆..
        count =this.engSysEmpMapper.updateById(emp);

        if(count == 0){
            throw new GlobalException("分配车辆失败");
        }

        return ServerResponse.ok("分配车辆成功");
    }

    /**
     * 获取业务员当前的情况
     * @param openId
     * @return
     */
    @Override
    public ServerResponse getEmpInfo(String openId) {
        EngSysEmp emp = this.engSysEmpMapper.selectOne(EngSysEmp.builder().openId(openId).build());
        // 下面填充信息内容
        Map<String,Object> result = Maps.newHashMap();
        result.put("emp",emp);
        result.put("deposit",this.engDepositMapper.selectById(emp.getDepositId()));
        result.put("car",this.engCarMapper.selectById(emp.getCarId()));
        return ServerResponse.ok(result);
    }

    /**
     * 修改用户的信息
     * @param emp
     * @return
     */
    @Override
    public ServerResponse editEmp(EngSysEmp emp) {
        int count = this.engSysEmpMapper.updateById(emp);
        if(count == 0){
            throw new GlobalException("修改用户基本信息失败");
        }

        return ServerResponse.ok("修改用户基本信息成功");
    }
}
